package rpcresponse

import (
	"gitee.com/xlizy/common-go/base/common_const"
	"gitee.com/xlizy/common-go/base/enums/common_error"
	"gitee.com/xlizy/common-go/base/response"
	"gitee.com/xlizy/common-go/utils/threadlocal"
	"gitee.com/xlizy/rpc-interface/rpc_pbs"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
	"reflect"
	"time"
)

func Succ() (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         0,
		Msg:          "",
		Success:      true,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	return result, nil
}

func Success(msg string, data proto.Message) (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         0,
		Msg:          msg,
		Success:      true,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	if data != nil {
		anyMsg, err := anypb.New(data)
		if err == nil {
			result.Data = anyMsg
		}
	}
	return result, nil
}

func SuccMsg(msg string) (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         0,
		Msg:          msg,
		Success:      true,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	return result, nil
}

func Err(errType any) (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         common_error.SystemError.Code(),
		Msg:          common_error.SystemError.Des(),
		Success:      false,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	defer func(r *rpc_pbs.RpcResult) {
		err := recover() // recover()内置函数，可以捕获到异常
		if err != nil {  //说明捕获到错误
		}
	}(result)
	code := reflect.ValueOf(errType).MethodByName("Code").Call(nil)[0]
	des := reflect.ValueOf(errType).MethodByName("Des").Call(nil)[0]
	result.Code = int32(code.Int())
	result.Msg = des.String()
	return result, nil
}

func Error(errType any, data proto.Message) (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         common_error.SystemError.Code(),
		Msg:          common_error.SystemError.Des(),
		Success:      false,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	defer func(r *rpc_pbs.RpcResult) {
		err := recover() // recover()内置函数，可以捕获到异常
		if err != nil {  //说明捕获到错误
		}
	}(result)
	code := reflect.ValueOf(errType).MethodByName("Code").Call(nil)[0]
	des := reflect.ValueOf(errType).MethodByName("Des").Call(nil)[0]
	result.Code = int32(code.Int())
	result.Msg = des.String()
	if data != nil {
		anyMsg, err := anypb.New(data)
		if err == nil {
			result.Data = anyMsg
		}
	}
	return result, nil
}

func ErrorMsg(msg string) (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         common_error.SystemError.Code(),
		Msg:          msg,
		Success:      false,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	return result, nil
}

func ErrorCus(bizRes *response.Response) (*rpc_pbs.RpcResult, error) {
	result := &rpc_pbs.RpcResult{
		Code:         bizRes.Code,
		Msg:          bizRes.Msg,
		Success:      bizRes.Success,
		TraceId:      threadlocal.GetTraceId(),
		ResponseTime: time.Now().Format(common_const.DataFormat),
	}
	if bizRes.Code == common_error.RequestArgumentNotValid.Code() {
		anyMsg, err := anypb.New(&rpc_pbs.InvalidParams{Items: bizRes.Data.([]string)})
		if err == nil {
			result.Data = anyMsg
		}
	}
	return result, nil
}
